#include <gtest/gtest.h>

#include <memory>

#include "Executor.hpp"
#include "PoseEq.hpp"
namespace adas
{
//测试化用例54：跑车向东前进
TEST(ExecutorTest,sportcar_should_return_x_plus_2_command_is_M_facing_is_E)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::SPORTS_CAR));

    //when
    executor->Execute("M");

    //then
    const Pose target({2, 0, 'E'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例55：跑车从东倒车
TEST(ExecutorTest,sportcar_should_return_x_minus_2_command_is_BM_facing_is_E)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::SPORTS_CAR));

    //when
    executor->Execute("BM");
    //then
    const Pose target({-2, 0, 'E'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例56：跑车向东加速
TEST(ExecutorTest,sportcar_should_return_x_plus_4_command_is_MM_facing_is_E)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::SPORTS_CAR));

    //when
    executor->Execute("FM");

    //then
    const Pose target({4, 0, 'E'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例57：跑车从东加速倒车
TEST(ExecutorTest,sportcar_should_return_x_minus_4_command_is_FBM_facing_is_E)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::SPORTS_CAR));
    //when
    executor->Execute("FBM");

    //then
    const Pose target({-4, 0, 'E'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例58：跑车向东左转
TEST(ExecutorTest,sportcar_should_return_facing_N_y_plus_1_command_is_L_facing_is_E)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::SPORTS_CAR));

    //when
    executor->Execute("L");

    //then
    const Pose target({0, 1, 'N'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例59：跑车向东左转倒车
TEST(ExecutorTest,sportcar_should_return_facing_S_y_plus_1_command_is_BL_facing_is_E)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::SPORTS_CAR));

    //when
    executor->Execute("BL");

    //then
    const Pose target({0, 1, 'S'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例60：跑车向东左转加速
TEST(ExecutorTest,sportcar_should_return_facing_N_x_plus_1_y_plus_1_command_is_FL_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::SPORTS_CAR));

    //when
    executor->Execute("FL");

    //then
    const Pose target({1, 1, 'N'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例61：跑车向东左转加速倒车
TEST(ExecutorTest,sportcar_should_return_facing_S_x_minus_1_y_minus_1_command_is_BFL_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::SPORTS_CAR));

    //when
    executor->Execute("FBL");
    //then
    const Pose target({-1, 1, 'S'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例62：跑车向东右转
TEST(ExecutorTest,sportcar_should_return_facing_S_y_minus_1_command_is_R_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::SPORTS_CAR));

    //when
    executor->Execute("R");

    //then
    const Pose target({0, -1, 'S'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例63：跑车向东右转倒车
TEST(ExecutorTest,sportcar_should_return_facing_N_y_minus_1_command_is_BR_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::SPORTS_CAR));

    //when
    executor->Execute("BR");

    //then
    const Pose target({0, -1, 'N'});
    ASSERT_EQ(target, executor->Query());

}
//测试化用例64：跑车向东右转加速
TEST(ExecutorTest,sportcar_should_return_facing_S_x_plus_1_y_minus_1_command_is_FR_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::SPORTS_CAR));
    //when
    executor->Execute("FR");

    //then
    const Pose target({1, -1, 'S'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例65：跑车向东右转加速倒车
TEST(ExecutorTest,sportcar_should_return_facing_N_x_minus_1_y_plus_1_command_is_BFR_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::SPORTS_CAR));
    //when
    executor->Execute("FBR");

    //then
    const Pose target({-1, -1, 'N'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例66：Bus向东前进
TEST(ExecutorTest,bus_should_return_x_plus_1_command_is_M_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::BUS));
    //when
    executor->Execute("M");
    //then
    const Pose target({1, 0, 'E'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例67：Bus向东倒车
TEST(ExecutorTest,bus_should_return_x_minus_1_command_is_BM_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::BUS));
    //when
    executor->Execute("BM");
    //then
    const Pose target({-1, 0, 'E'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例68：Bus向东加速
TEST(ExecutorTest,bus_should_return_x_plus_2_command_is_MM_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::BUS));
    //when
    executor->Execute("FM");
    //then
    const Pose target({2, 0, 'E'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例69：Bus向东加速倒车
TEST(ExecutorTest,bus_should_return_x_minus_2_command_is_FBM_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::BUS));
    //when
    executor->Execute("FBM");
    //then
    const Pose target({-2, 0, 'E'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例70：Bus向东左转
TEST(ExecutorTest,bus_should_return_facing_N_x_plus_1_command_is_L_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::BUS));
    //when
    executor->Execute("L");
    //then
    const Pose target({1, 0, 'N'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例71：Bus向东左转倒车
TEST(ExecutorTest,bus_should_return_facing_S_x_minus_1_command_is_BL_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::BUS));
    //when
    executor->Execute("BL");
    //then
    const Pose target({-1, 0, 'S'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例72：Bus向东左转加速
TEST(ExecutorTest,bus_should_return_facing_N_x_plus_2_command_is_FL_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::BUS));
    //when
    executor->Execute("FL");
    //then
    const Pose target({2, 0, 'N'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例73：Bus向东左转加速倒车
TEST(ExecutorTest,bus_should_return_facing_S_x_minus_2_command_is_BFL_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::BUS));
    //when
    executor->Execute("FBL");
    //then
    const Pose target({-2, 0, 'S'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例74：Bus向东右转
TEST(ExecutorTest,bus_should_return_facing_S_x_plus_1_command_is_R_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::BUS));
    //when
    executor->Execute("R");
    //then
    const Pose target({1, 0, 'S'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例75：Bus向东右转倒车
TEST(ExecutorTest,bus_should_return_facing_N_x_minus_1_command_is_BR_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::BUS));
    //when
    executor->Execute("BR");
    //then
    const Pose target({-1, 0, 'N'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例76：Bus向东右转加速
TEST(ExecutorTest,bus_should_return_facing_S_x_plus_2_command_is_FR_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::BUS));
    //when
    executor->Execute("FR");
    //then
    const Pose target({2, 0, 'S'});
    ASSERT_EQ(target, executor->Query());
}
//测试化用例77：Bus向东右转加速倒车
TEST(ExecutorTest,bus_should_return_facing_N_x_minus_2_command_is_BFR_facing_is_E){
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::BUS));
    //when
    executor->Execute("FBR");
    //then
    const Pose target({-2, 0, 'N'});
    ASSERT_EQ(target, executor->Query());
}

}